package org.ainlolcat.ainscience.entity;

import org.ainlolcat.ainscience.UI.SimpleEntityPanel;
import org.ainlolcat.ainscience.UpdateListener;
import org.ainlolcat.ainscience.column.Column;
import org.ainlolcat.ainscience.entity.links.Link;
import org.ainlolcat.ainscience.statistics.Statistic;
import org.ainlolcat.ainscience.templates.Template;
import org.apache.log4j.Logger;

import javax.swing.*;
import java.text.DecimalFormat;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: ain
 * Date: 11.02.12
 * Time: 2:42
 * some operation is really boring to write again and again
 */
public abstract class AbstractEntity implements Entity{
    private static Logger log = Logger.getLogger(AbstractEntity.class);

    protected Template template;
    protected String type;
    protected Integer ID;
    protected String name;
    protected TreeMap<String,Column> data = new TreeMap<String, Column>();
    protected boolean isPersistent = true;
    protected boolean visible = true;
    protected List<UpdateListener> listeners;
    protected Statistic statistic;

    @Deprecated
    public Column getColumnById(Integer id) {
        String leadingIndex = String.format("%03d", id);
        for(String key : data.keySet())
        {
            if (key.startsWith(leadingIndex))
                return data.get(key);
        }
        throw new RuntimeException("Cannot find for " + leadingIndex);
    }

    public Column getColumnByOrder(Integer idx){
        int i = 0;
        for(String key : data.keySet())
        {
            if (i == idx)
                return data.get(key);
            i++;
        }
        throw new RuntimeException("Size was " + getColumnCount() + " but requested idx was " + idx);
    }

    public Column getColumnByName(String name){
        for (Column column: data.values()){
            if (column.getName().equals(name)){
                return column;
            }
        }
        return null;
    }

    public Column getXColumn(String axis){
        String axisIdx = axis.substring(1,axis.length());
        for (Column column: data.values()){
            if (column.getAxis().startsWith("x")){
                String columnIdx = column.getAxis().substring(1,column.getAxis().length());
                if (axisIdx.equals(columnIdx)){
                    return column;
                }
            }
        }
        return null;
    }

    public void setColumn(Column column,Integer order){
        data.put(String.format("%03d", order) + column.getName(),column);
        throwUpdateEvent(UpdateListener.UPDATE_ENTITY_COLUMN);
    }

    public int getColumnCount(){
        return data.size();
    }

    public int getRowCount(){
        return data.values().iterator().next().size();
    }

    public boolean isPersistent(){
        return isPersistent;
    }

    public boolean isVisible(){
        return visible;
    }

    public void setPersistent(boolean pers){
        isPersistent = pers;
    }
 
    public JPanel getRenderer() {
        return new SimpleEntityPanel(this);
    }

    public Template getTemplate() {
        return template;
    }

    public String getType() {
        return type;
    }

    public void setID(Integer id){
        this.ID = id;
    }

    public Integer getID(){
        return ID;
    }

    public void setName(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public void setStatistic(Statistic statistic) {
        this.statistic = statistic;
        //throwUpdateEvent(UpdateListener.UPDATE_ENTITY_STATISTICS);
    }

    public Statistic getStatistic() {
        return statistic;
    }

    public boolean registerListener(UpdateListener listener) {
        if (listeners == null){
            listeners = new ArrayList<UpdateListener>();
            listeners.add(listener);
            return true;
        }
        if (!listeners.contains(listener)){
            listeners.add(listener);
            return true;
        }
        return false;
    }

    public boolean removeListener(UpdateListener listener) {
        if (listeners == null){
            return false;
        }
        if (listeners.contains(listener)){
            listeners.remove(listener);
            return true;
        }
        return false;
    }

    protected void throwUpdateEvent(int action){
        //log.debug("Update event: " + getName() + " action:" +  action);
        if (listeners==null || listeners.isEmpty()) return;
        for (UpdateListener listener : listeners){
            listener.onEntityUpdate(this, action);
        }
    }

    protected void throwUpdateEvent(){
        throwUpdateEvent(UpdateListener.UPDATE_ACTION_UNKNOWN);
    }

    public Link getLink(String name) {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public void setLink(Link link) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public Collection<Link> getLinks() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public List<String> getDependencies() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }
}
